#include "CCmdInnerFightEnd.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "commmsg.h"
#include "MsgFightEnd.pb.h"
#include "../map/CMapView.h"
#include "MsgComm.pb.h"
#include "MsgMapInfo.pb.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_FIGHT_END, CCmdInnerFightEnd);

int CCmdInnerFightEnd::Do(void* pData)
{
    if (pData != NULL)
    {
        CT_ERROR(("inner cmd CCmdInnerFightEnd get data"));
        return Done(RET_OK);
    }

    if (pstMainCtrl == NULL)
    {
        CT_ERROR(("mainctrl point is null"));
        return Done(RET_SYSTEM_FAIL);
    }

    //统一在这里初始化关键值
    _bIsLeftWin = false;
    _bIsPrepareWrong = false;
    _bHasDealBattle = false;
    _bIsReverWinning = false;

    _iMapIndex = 0;
    _iDataIndex = 0;
    _iWrongIndex = 0;
    _iReportIndex = 0;
    _iWinningIndex = -1;

    return LogicDo(RET_OK);
}

int CCmdInnerFightEnd::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        return Done(iRet);
    }

    int iIndex = 0;

	switch (_iSubCmd)
	{
    case CFightEndMgr::CMD_INNER_FIGHT_END_SEND_INFO:
        {
            PREPARE_PLAYER_DETAIL_EX1_INFO(this, _uiGID);
            ASSERT_PLAYER_DETAIL_EX1_INFO(_uiGID);

            iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no ex1 data user (%u)", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerDetailInfoEx1& stPlayerDetailEx1 =
                pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

            //注意需要在这里先更新一下数据
            pstMainCtrl->m_stFightEndMgr.CheckFightEndData(stPlayerDetailEx1);

            MsgAnsFightEnd stAns;
            stAns.set_sub_type(CFightEndMgr::CMD_FIGHT_END_SUB_WAIT);
            stAns.set_gid(_uiGID);
            stAns.set_award_time(stPlayerDetailEx1._stFightEnd._chAwardNum);
            stAns.set_end_time(
                CMainCtrl::m_pstMain->m_stActMgr.GetEndTime(ACT_ID_FIGHT_END));
            if (_bIsLeft)
            {
                stAns.set_is_left(1);
            }
            else
            {
                stAns.set_is_left(0);
            }
            iRet = pstMainCtrl->NotifyOnlineUser(_uiGID, ID_MAIN_FIGHT_END,
                stAns, false);
            return Done(iRet);
        }
        break;
    case CFightEndMgr::CMD_INNER_FIGHT_END_CHECK_BAG:
        {
            PREPARE_PLAYER_BASE_INFO(this, _uiGID);
            ASSERT_PLAYER_PREPARED(_uiGID);

            PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
            ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

            iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no base data user(%u)", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerBaseInfo& stPlayerBase =
                pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

            iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no online data user %u", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerOnlineData& stPlayerOnline =
                pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

            //没有足够的背包格子不能战斗
            if (stPlayerOnline._stUserStorage.GetBagEmptyGridCount() <
                    CFightEndMgr::MACRO_FIGHT_END_BATTLE_BAG_NUM)
            {
                //先下发一战到底错误响应
                pstMainCtrl->ReturnMsgHead(_uiGID, ID_MAIN_FIGHT_END,
                    ERROR_FIGHT_END_BAG_NOT_ENOUGH);

                pstMainCtrl->m_stFightEndMgr.MoveOutRoleFromMap(
                    pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                    stPlayerOnline);

                pstMainCtrl->m_stFightEndMgr.MoveOutRoleWithoutMoveAns(
                    pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                    stPlayerOnline);

                return Done(ERROR_FIGHT_END_BAG_NOT_ENOUGH);
            }
        }
        break;
    case CFightEndMgr::CMD_INNER_FIGHT_END_LEAVE_MAP:
        {
            PREPARE_PLAYER_BASE_INFO(this, _uiGID);
            ASSERT_PLAYER_PREPARED(_uiGID);
            
            PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
            ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

            iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no base data user(%u)", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerBaseInfo& stPlayerBase =
                pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

            iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no online data user %u", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerOnlineData& stPlayerOnline =
                pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

            iRet = pstMainCtrl->m_stFightEndMgr.MoveOutRoleFromMap(
                pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                stPlayerOnline);

            iRet = pstMainCtrl->m_stFightEndMgr.MoveOutRoleWithoutMoveAns(
                pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                stPlayerOnline);

            return Done(iRet);
        }
        break;
    case CFightEndMgr::CMD_INNER_FIGHT_END_PREPARE_DATA:
        {
            for ( ; _iDataIndex < _stFightEndData.GetRoleSize(); ++_iDataIndex)
            {
                CFightEndUnit& stRoleUnit =
                    _stFightEndData.GetRoleUnit(_iDataIndex);
                _uiGID = stRoleUnit.GetGID();
                if (_uiGID <= 0) {continue;}

                PREPARE_PLAYER_BASE_INFO(this, _uiGID);
                ASSERT_PLAYER_PREPARED(_uiGID);
                
                PREPARE_PLAYER_DETAIL_INFO(this, _uiGID);
                ASSERT_PLAYER_DETAIL_PREPARED(_uiGID);

                PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
                ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

                iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no base data user(%u)", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerBaseInfo& stPlayerBase =
                    pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
                
                iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no detail data user(%u)", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerDetailInfo& stPlayerDetail =
                    pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

                iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no online data user %u", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerOnlineData& stPlayerOnline =
                    pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

                if (_iDataIndex < MAX_FIGHT_END_ROLE_SIDE)
                {
                    iRet = pstMainCtrl->m_stBattleMgr.TransPlayerAndPartner(
                        stPlayerBase, stPlayerDetail, stPlayerOnline,
                        _stFightEndData.GetLeftTeam(_iDataIndex), true);
                }
                else
                {
                    iRet = pstMainCtrl->m_stBattleMgr.TransPlayerAndPartner(
                        stPlayerBase, stPlayerDetail, stPlayerOnline,
                        _stFightEndData.GetRightTeam(
                            _iDataIndex - MAX_FIGHT_END_ROLE_SIDE), false);
                }

                if (iRet)//有个体战斗数据准备出错
                {
                    CT_ERROR(("fight end prepare role(%u) battle error(%d)",
                        _uiGID,iRet));
                    _bIsPrepareWrong = true;
                    _iDataIndex = _stFightEndData.GetRoleSize();
                    break;
                }
            }
#if 0
            for ( ; _bIsPrepareWrong &&
                        _iWrongIndex < _stFightEndData.GetRoleSize();
                            ++_iWrongIndex)
            {
                CFightEndUnit& stRoleUnit =
                    _stFightEndData.GetRoleUnit(_iWrongIndex);
                _uiGID = stRoleUnit.GetGID();
                if (_uiGID <= 0) {continue;}

                PREPARE_PLAYER_BASE_INFO(this, _uiGID);
                ASSERT_PLAYER_PREPARED(_uiGID);
                
                PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
                ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

                iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no base data user(%u)", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerBaseInfo& stPlayerBase =
                    pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
                
                iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no online data user %u", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerOnlineData& stPlayerOnline =
                    pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

                if (pstMainCtrl->m_stFightEndMgr.GetMapID()
                        != stPlayerOnline._uiNowMapID)
                {
                    continue;
                }

                pstMainCtrl->m_stFightEndMgr.MoveOutRoleWithoutMoveAns(
                    pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                    stPlayerOnline);
            }
#endif
            if (_bIsPrepareWrong)
            {
                return Done(iRet);
            }

            if (!_bHasDealBattle)
            {
                iRet = pstMainCtrl->m_stFightEndMgr.DealBattle(_stFightEndData,
                    _bIsLeftWin, _iWinningIndex, _bIsReverWinning);
                if (iRet)
                {
                    CT_ERROR(("fight end deal battle error(%d)!", iRet));
                    return Done(iRet);
                }
                _bHasDealBattle = true;
            }

            for ( ; _iReportIndex < _stFightEndData.GetRoleSize();
                        ++_iReportIndex)
            {
                CFightEndUnit& stRoleUnit =
                    _stFightEndData.GetRoleUnit(_iReportIndex);
                _uiGID = stRoleUnit.GetGID();
                if (_uiGID <= 0) {continue;}

                PREPARE_PLAYER_BASE_INFO(this, _uiGID);
                ASSERT_PLAYER_PREPARED(_uiGID);
                
                PREPARE_PLAYER_DETAIL_EX1_INFO(this, _uiGID);
                ASSERT_PLAYER_DETAIL_EX1_INFO(_uiGID);

                PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
                ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

                iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no base data user(%u)", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerBaseInfo& stPlayerBase =
                    pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
                
                iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(
                    _uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no ex1 data user (%u)", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerDetailInfoEx1& stPlayerDetailEx1 =
                    pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

                iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no online data user %u", _uiGID));
                    return Done(RET_SYSTEM_FAIL);
                }
                CPlayerOnlineData& stPlayerOnline =
                    pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

                if (_iReportIndex < MAX_FIGHT_END_ROLE_SIDE)
                {
                    iRet = pstMainCtrl->m_stFightEndMgr.BattleReport(
                        stPlayerBase, stPlayerDetailEx1, stPlayerOnline, true,
                        (_bIsLeftWin ? true : false));
                    if (iRet)
                    {
                        CT_ERROR(("fight end report role(%u) error(%d)!",
                            _uiGID,iRet));
                    }
                }
                else
                {
                    iRet = pstMainCtrl->m_stFightEndMgr.BattleReport(
                        stPlayerBase, stPlayerDetailEx1, stPlayerOnline, false,
                        (_bIsLeftWin ? false : true));
                    if (iRet)
                    {
                        CT_ERROR(("fight end report role(%u) error(%d)!",
                            _uiGID,iRet));
                    }
                }
            }

            if (_iWinningIndex >= 0
                    && _iWinningIndex < _stFightEndData.GetRoleSize())
            {
                CFightEndUnit& stRoleUnit =
                    _stFightEndData.GetRoleUnit(_iWinningIndex);
                _uiGID = stRoleUnit.GetGID();
                if (_uiGID > 0)
                {
                    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
                    ASSERT_PLAYER_PREPARED(_uiGID);
                    
                    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(
                        _uiGID);
                    if (iIndex < 0)
                    {
                        CT_ERROR(("no base data user(%u)", _uiGID));
                        return Done(RET_SYSTEM_FAIL);
                    }
                    CPlayerBaseInfo& stPlayerBase =
                        pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

                    MsgTips stTips;
                    if (_bIsReverWinning)
                    {
                        stTips.set_type(TIPS_FIGHTEND_REVER_WINNING_STREAK);
                    }
                    else
                    {
                        stTips.set_type(TIPS_FIGHTEND_WINNING_STREAK);
                    }

                    stTips.add_tip_argument(stPlayerBase._sRoleName());
                    pstMainCtrl->SendOnlineTips(stTips);
                    pstMainCtrl->FlushSendCache();
                }
            }
#if 0
            for ( ; _iMapIndex < _stFightEndData.GetRoleSize(); ++_iMapIndex)
            {
                CFightEndUnit& stRoleUnit =
                    _stFightEndData.GetRoleUnit(_iMapIndex);
                _uiGID = stRoleUnit.GetGID();
                if (_uiGID <= 0) {continue;}

                PREPARE_PLAYER_BASE_INFO(this, _uiGID);
                ASSERT_PLAYER_PREPARED(_uiGID);
                
                PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
                ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

                iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no base data user(%u)", _uiGID));
                    continue;
                }
                CPlayerBaseInfo& stPlayerBase =
                    pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

                iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
                if (iIndex < 0)
                {
                    CT_ERROR(("no online data user %u", _uiGID));
                    continue;
                }
                CPlayerOnlineData& stPlayerOnline =
                    pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

                if (pstMainCtrl->m_stFightEndMgr.GetMapID()
                        != stPlayerOnline._uiNowMapID)
                {
                    continue;
                }

                pstMainCtrl->m_stFightEndMgr.MoveOutRoleWithoutMoveAns(
                    pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                    stPlayerOnline);

            }
#endif
            return Done(iRet);
        }
        break;
    case CFightEndMgr::CMD_INNER_FIGHT_END_LEAVE_MAP_NO_ANS:
        {
            PREPARE_PLAYER_BASE_INFO(this, _uiGID);
            ASSERT_PLAYER_PREPARED(_uiGID);
            
            PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);
            ASSERT_PLAYER_ONLINE_DATA_PREPARED(_uiGID)

            iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no base data user(%u)", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerBaseInfo& stPlayerBase =
                pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

            iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no online data user %u", _uiGID));
                return Done(RET_SYSTEM_FAIL);
            }
            CPlayerOnlineData& stPlayerOnline =
                pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

            iRet = pstMainCtrl->m_stFightEndMgr.MoveOutRoleWithoutMoveAns(
                pstMainCtrl->m_stFightEndMgr.GetMapID(), stPlayerBase,
                stPlayerOnline);

            return Done(iRet);
        }
        break;
	default:
        CT_ERROR(("fight end cmd inner unknow sub cmd(%d)",_iSubCmd));
        return Done(ERROR_MAIN_SUB_CMD);
	}

    return Done(RET_OK);
}

